Add random kwarg to DensityDist #2106#2805
Conversation
pymc3/distributions/distribution.py
Outdated
There was a problem hiding this comment.
I would move this to before *args to not mess with the order.
pymc3/distributions/distribution.py
Outdated
There was a problem hiding this comment.
I don't think this works, you need to call self.rand(*args, **kwargs) and add those as well to the method call signature.
There was a problem hiding this comment.
Yeah that makes more sense. 👍
|
That's a good start, definitely needs a test. |
|
Which file would be appropriate for its test? I am confused between test_distributions.py and test_distributions_random.py |
5a6a174 to
8ecd3a3
Compare
|
I would add a test to https://github.com/pymc-devs/pymc3/blob/718dab9ded5bf99d2fcfcd4ec8e2cf9769bb216a/pymc3/tests/test_distributions_random.py where you create a |
pymc3/distributions/distribution.py
Outdated
There was a problem hiding this comment.
PEP8 requires spaces after arguments
pymc3/distributions/distribution.py
Outdated
|
@twiecki Could you please provide the link to the gist or line number of the test for Normal random method you mentioned, I couldn't find it? |
This is the test I came up with, but it is throwing error when I run it locally. The error I got is, The problem is in the passing of functions (for logp and random) as parameters in the dictionary, I can't figure out any workaround for this can you help me out on this @twiecki? |
|
This is a bit more tricky than I thought. This is how far I got: def custom_random(self, point=None, size=None, repeat=None):
mu, tau, _ = draw_values([self.mu, self.tau, self.sd],
point=point)
return generate_samples(stats.norm.rvs, loc=mu, scale=tau**-0.5,
dist_shape=self.shape,
size=size)
def test_density_dist(self):
def ref_rand(size, mu, sd):
return st.norm.rvs(size=size, loc=mu, scale=sd)
def create_custom_dens(name, mu=0, sd=1, shape=None, transform=None):
return pm.DensityDist(name, lambda value: np.log(st.norm(loc=mu, scale=sd).pdf(value)), #logp
random=custom_random)
pymc3_random(create_custom_dens, {'mu': R, 'sd': Rplus}, ref_rand=ref_rand)A couple of notes:
Hopefully that gets us a step closer. |
|
Thank you for such a detailed reply, I will try what you have suggested and get back to you once I have some working version ready. |
|
@twiecki are you familiar with any other similar test that could serve as a reference? My efforts have not lead to anything, I think looking at some example would be helpful. |
|
@Vaibhavdixit02 implementing test could be tricky, you might find this PR useful: #2443 |
|
Along the lines of the test for But I am getting Can't figure out why it says multiple arguments for |
|
Because the first argument is already the |
8ecd3a3 to
b5ea182
Compare
|
This test was passing locally for me, please tell me if there is some conceptual error. 🙂 |
|
That looks great! Would it be easy from here to do the same put calling |
|
The problem with |
|
Oh it needs a |
|
I think that would be the simplest and most straightforward approach, to create a separate model instance for |
|
@Vaibhavdixit02 The test I'm imagining would not test that sampling is valid. It would literarily just be a function that creates a model context, creates a DensityDist with random, and then does ppc and makes sure there is no exception and the |
|
Okay sure. I think we could use the |
187d12e to
cae5c86
Compare
cae5c86 to
216da86
Compare
|
Definitely.
…On Feb 2, 2018 05:44, "Vaibhav Kumar Dixit" ***@***.***> wrote:
Okay sure. I think we could use the normal logp and random method in this
test too?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2805 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AApJmHq6a9vnGQ5LjiviZLUJhYSARbg8ks5tQpKUgaJpZM4RigT1>
.
|
|
@twiecki have added that test. 🙂 |
There was a problem hiding this comment.
Instead of returning we want to something like here: https://github.com/Vaibhavdixit02/pymc3/blob/216da86a6c8f9ae6516d133bc198ac45d678e716/pymc3/tests/test_distributions_random.py#L73 npt.assert_true(len(ppc) > 0, 'length of ppc sample is zero'). Check the np.testing submodule and other parts of the code for various usage patterns.
There was a problem hiding this comment.
This looks great. Does it work with a scipy distribution inside a lambda as well?
There was a problem hiding this comment.
I didn't quite get that, can you elaborate on that a little?
My interpretation is something like
def mynormal_logp():
norm_dist_logp = st.norm.logpdf
norm_dist_random = np.random.normal
density_dist = pm.DensityDist('density_dist', norm_dist_logp, random=norm_dist_random)
is that what you meant?
There was a problem hiding this comment.
I'll test this locally and check! BTW does PyMC3 handle scipy distributions in general?
|
This is shaping up nicely. See minor comments to resolve as well as the bad merge. Also, please add this (with credit) to the release-notes. |
216da86 to
905e83a
Compare
|
@twiecki added the test with scipy's normal distribution, the test passed locally but I am not very sure if it is correct, please provide feedback if it needs to be changed. |
|
This looks great, thanks for figuring this out! |
|
Only need to add this to the release notes. |
|
|
||
| try: | ||
| ppc = pm.sample_ppc(trace, samples=500, model=model, size=100) | ||
| if len(ppc) > 0: |
There was a problem hiding this comment.
Just need to check if len(ppc) == 0
| normal_dist = pm.Normal.dist() | ||
| density_dist = pm.DensityDist('density_dist', normal_dist.logp, random=normal_dist.random) | ||
| step = pm.Metropolis() | ||
| trace = pm.sample(5000, step) |
There was a problem hiding this comment.
can do fewer steps here, e.g. 100 with tuning=0.
|
Should I add it to the release notes or will the maintainers do that? |
|
You should.
…On Sun, Feb 4, 2018 at 8:20 PM, Vaibhav Kumar Dixit < ***@***.***> wrote:
Should I add it to the release notes or will the maintainers do that?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2805 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AApJmHNtNrq_4sZLzFYWYUTXYv5x9X2aks5tRgMXgaJpZM4RigT1>
.
|
|
Congrats @Vaibhavdixit02! |
|
Yay! 😄 |
| """Distribution based on a given log density function.""" | ||
|
|
||
| def __init__(self, logp, shape=(), dtype=None, testval=0, *args, **kwargs): | ||
| def __init__(self, logp, shape=(), dtype=None, testval=0, random=None, *args, **kwargs): |
There was a problem hiding this comment.
Should add this to the doc-string.
| with model: | ||
| norm_dist_logp = st.norm.logpdf | ||
| norm_dist_random = np.random.normal | ||
| density_dist = pm.DensityDist('density_dist', normal_dist_logp, random=normal_dist_random) |
There was a problem hiding this comment.
I just realized, I think we need to turn this into an observed to actually get sampling from this.
|
|
||
| try: | ||
| ppc = pm.sample_ppc(trace, samples=500, model=model, size=100) | ||
| if len(ppc) == 0: |
|
@Vaibhavdixit02 Sorry, I realized two more things here (see new comments). Could you also address those in a separate PR? |
As per the discussion with @twiecki in #2106 I have implemented the
randommethod forDensityDist, this is my first PR in PyMC3 so any feedbacks are very welcome. 😄